package top.mccat.raven.listener;

import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import top.mccat.raven.factory.ConfigFactory;
import top.mccat.raven.item.MyItem;
import top.mccat.raven.utils.handler.StrengthCommandHandler;
import java.util.logging.Logger;

/**
 * @ClassName: OnDamageListener
 * @Description: TODO
 * @Author: Raven
 * @Date: 2021/7/7
 * @Version: 1.0
 */
public class OnDamageListener implements Listener {
    private final int REMOTE = 1,MELEE = 2,ARMOR = 0;
    private JavaPlugin plugin;
    private ConfigFactory factory;
    private float levelDamagePrimary,levelDamageMiddle,levelDamageHigh;
    private float levelDefencePrimary,levelDefenceMiddle,levelDefenceHigh;
    private Player defencer,damager;
    private Logger logger;
    private MyItem item;
    public OnDamageListener(JavaPlugin plugin){
        this.plugin = plugin;
        factory = new ConfigFactory(plugin);
        logger = plugin.getLogger();
        readItemExtra();
    }

    public void readItemExtra(){
        levelDamagePrimary = factory.getLevelDamage("weapon.primary");
        levelDamageMiddle = factory.getLevelDamage("weapon.middle");
        levelDamageHigh = factory.getLevelDamage("weapon.high");
        levelDefencePrimary = factory.getLevelDamage("armor.primary");
        levelDefenceMiddle = factory.getLevelDamage("armor.middle");
        levelDefenceHigh = factory.getLevelDamage("armor.high");
        /*logger.info(this.toString());*/
    }

    @EventHandler(priority = EventPriority.HIGH)//高优先级
    public void modifyEntityDamage(EntityDamageByEntityEvent attackEvent) {
        if(attackEvent.getCause() == EntityDamageEvent.DamageCause.ENTITY_ATTACK) {
            if (attackEvent.getDamager() instanceof Player) {
                damager = (Player) attackEvent.getDamager();
                int level = 0;
                if ((level = getStrengthWeaponLevel(damager)) > 0) {
                    if(item.getItemMaterial() != Material.BOW && item.getItemMaterial() != Material.CROSSBOW) {
                        float damage = (float) (modifyAttackDamage(level) + attackEvent.getDamage());
                        /*logger.info("攻击伤害：" + damage + " 基础伤害" + attackEvent.getDamage());*/
                        attackEvent.setDamage(damage);
                    }
                }
            }if (attackEvent.getEntity() instanceof Player) {
                defencer = (Player) attackEvent.getEntity();
                int[] levels= getStrengthArmorLevel(defencer);
                if(levels[0]>0){
                    float damage = 0;
                    for(int level : levels){
                        damage += modifyDefenceDamage(level);
                    }
                    /*logger.info("攻击抵御伤害："+damage);*/
                    if(damage > attackEvent.getDamage()){
                        attackEvent.setDamage(0);
                    }else {
                        attackEvent.setDamage(attackEvent.getDamage()-damage);
                    }
                }
            }
        }else if (attackEvent.getCause() == EntityDamageEvent.DamageCause.PROJECTILE) {
            if(damager instanceof Player){
                int level = 0;
                if((level = getStrengthWeaponLevel(damager))>0){
                    float damage = (float) (modifyAttackDamage(level)+attackEvent.getDamage());
                    /*logger.info("攻击伤害："+damage+ " 基础伤害"+ attackEvent.getDamage());*/
                    attackEvent.setDamage(damage);
                }
            }if(attackEvent.getEntity() instanceof Player){
                defencer = (Player) attackEvent.getEntity();
                int[] levels= getStrengthArmorLevel(defencer);
                if(levels[0]>0){
                    float damage = 0;
                    for(int level : levels){
                        damage += modifyDefenceDamage(level);
                    }
                    /*logger.info("射击抵御伤害："+damage);*/
                    if(damage > attackEvent.getDamage()){
                        attackEvent.setDamage(0);
                    }else {
                        attackEvent.setDamage(attackEvent.getDamage()-damage);
                    }
                }
            }
        }
    }

    @EventHandler(priority = EventPriority.HIGHEST)//高优先级
    public void modifyShotDamage(ProjectileLaunchEvent shotEvent) {
        if(shotEvent.getEntity().getShooter() instanceof Player){
            this.damager = (Player) shotEvent.getEntity().getShooter();
        }
    }

    private float modifyAttackDamage(int level){
        float damage = 0;
        if(level<=10){
            damage = levelDamagePrimary*level;
        }else if(level>10 && level<=20){
            damage = levelDamagePrimary*10 + levelDamageMiddle*(level-10);
        }else if(level>20 && level<=30){
            damage = levelDamagePrimary*10 + levelDamageMiddle*10 + levelDamageHigh*(level-20);
        }
        return damage;
    }

    private float modifyDefenceDamage(int level){
        float defence = 0;
        if(level<=10){
            defence = levelDefencePrimary*level;
        }else if(level>10 && level<=20){
            defence = levelDefencePrimary*10 + levelDefenceMiddle*(level-10);
        }else if(level>20 && level<=30){
            defence = levelDefencePrimary*10 + levelDefenceMiddle*10 + levelDefenceHigh*(level-20);
        }
        return defence;
    }

    public void setFactory(ConfigFactory factory) {
        this.factory = factory;
    }

    private int[] getStrengthArmorLevel(Player player){
        int level[] = {0,0,0,0};
        int count = 0;
        for(ItemStack stack : player.getInventory().getArmorContents()){
            item = new MyItem(player,stack);
            if((item.getLevel(StrengthCommandHandler.Title))>0){
                level[count]= item.getLevel(StrengthCommandHandler.Title);
                count++;
            }
        }
        return level;
    }

    private int getStrengthWeaponLevel(Player player){
        if(player.getInventory().getItemInMainHand().getType() != Material.AIR || player.getInventory().getItemInMainHand() != null){
            item = new MyItem(player);
            item.setStrengthStack(player.getInventory().getItemInMainHand());
            int level;
            if((level = item.getLevel(StrengthCommandHandler.Title))>0){
                return level;
            }
        }
        return -1;
    }

    @Override
    public String toString() {
        return "OnDamageListener{" +
                ", plugin=" + plugin +
                ", factory=" + factory +
                ", levelDamagePrimary=" + levelDamagePrimary +
                ", levelDamageMiddle=" + levelDamageMiddle +
                ", levelDamageHigh=" + levelDamageHigh +
                ", levelDefencePrimary=" + levelDefencePrimary +
                ", levelDefenceMiddle=" + levelDefenceMiddle +
                ", levelDefenceHigh=" + levelDefenceHigh +
                '}';
    }
}
